package com.younge.spring.service.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.younge.spring.api.result.MenuListResult;
import com.younge.spring.api.result.MenuMeta;
import com.younge.spring.repository.dao.SysMenu;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class SysMenuTreeBuilder {

    public static List<MenuListResult> buildTree(List<SysMenu> all, boolean notCotainButton) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);

        List<MenuListResult> list = new ArrayList<>(all.stream().map(e -> {
            try {
                MenuListResult m = objectMapper.readValue(objectMapper.writeValueAsString(e), MenuListResult.class);
                m.setPid(e.getParentId());
                m.setOrder(e.getOrderNum());
                m.setMeta(StringUtils.hasText(e.getMate()) ?
                        objectMapper.readValue(e.getMate(), MenuMeta.class) : null);
                return m;
            } catch (JsonProcessingException ex) {
                throw new RuntimeException(ex);
            }
        }).toList());

        Map<Long, MenuListResult> map = list.stream().collect(Collectors.toMap(MenuListResult::getId, r -> r));

        List<MenuListResult> roots = new ArrayList<>();
        for (MenuListResult node : list) {
            if (notCotainButton && "button".equals(node.getType())) {
                continue;
            }
            if (node.getPid() == 0) {
                roots.add(node);
            } else {
                MenuListResult parent = map.get(node.getPid());
                if (parent != null) {
                    parent.getChildren().add(node);
                }
            }
        }
        return roots;
    }

}